package dominio.dao;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import hibernate.HibernateUtilities;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import dominio.bean.*;

public class HibernateDAO {
	private static HibernateDAO instancia = null;
	private static SessionFactory sessionFactory = null;
	private Session session = null;
	
	private HibernateDAO(){
		
	}
	
	public static HibernateDAO getInstancia(){
		if(instancia == null)
		{
			sessionFactory = HibernateUtilities.getSession();
			instancia = new HibernateDAO();
		}
		return instancia;
	}
	
	private Session getSession(){
		if (session==null)
			session = sessionFactory.openSession();
		return session;
	}
	
	public void closeSession(){
		if(session != null)
			session.close();
	}
	
	public void grabarPesos (HashSet<Peso> pesos) {
		try{
		Session s = getSession();
		s.beginTransaction();
		for(Peso p : pesos)
		{
			s.persist(p);
		}
		s.flush();
		s.getTransaction().commit();		
		}
		catch (Exception ex){
			ex.printStackTrace();
			
		}
	}
	
	public void grabarSubclase(HashSet<SubClase> subclases)	{
		try{
		Session s = getSession();
		s.beginTransaction();
		for (SubClase  sc: subclases )
		{
			s.persist(sc);
		}
		s.flush();
		s.getTransaction().commit();
		}
		catch (Exception ex){
			ex.printStackTrace();
			
		}
	}
	
	public void grabarProducto(HashSet<Producto> productos)	{
		try{
		Session s = getSession();
		s.beginTransaction();
		for(Producto prod: productos)
		{
			s.persist(prod);
		}
		s.flush();
		s.getTransaction().commit();
		}
		catch (Exception ex){
			ex.printStackTrace();
			
		}
	}
	
	public void grabarEmpresaDeTransporte(HashSet<EmpresaTransporte> empresasTransportes) {
		try{
		Session s = getSession();
		s.beginTransaction();
		for(EmpresaTransporte emp : empresasTransportes)
		{
			s.persist(emp);
		}
		s.flush();
		s.getTransaction().commit();
		}
		catch (Exception ex){
			ex.printStackTrace();
			
		}
	}
	
	public void grabarCodigosPostales(HashSet<CodigoPostal> codigosPostales) {
		try{
		Session s = getSession();
		s.beginTransaction();
		for(CodigoPostal cp : codigosPostales)
		{
			s.persist(cp);
		}
		s.flush();
		s.getTransaction().commit();
		}
		catch (Exception ex){
			ex.printStackTrace();
			
		}
	}
	
	public void grabarTarifa(HashSet<Tarifa> tarifas) {
		try{
		Session s = getSession();
		s.beginTransaction();
		for(Tarifa t : tarifas)
		{
			s.persist(t);
		}
		s.flush();
		s.getTransaction().commit();
		}
		catch (Exception ex){
			ex.printStackTrace();
			
		}
	}
	
	public void grabarFormularioCompraProductos(HashSet<FormularioCompraProductos> formularioCompraProductos){
		try{
		Session s = getSession();
		s.beginTransaction();
		for(FormularioCompraProductos formulario: formularioCompraProductos) {
			s.persist(formulario);
		}
		s.flush();
		s.getTransaction().commit();
		}
		catch (Exception ex){
			ex.printStackTrace();
			
		}
	}
	
	public Integer grabarLiquidacion(Liquidacion liquidacion){
		try{
			Liquidacion l=new Liquidacion();
			
			Session s = getSession();
			s.beginTransaction();
			l=(Liquidacion) s.merge(liquidacion);
			s.flush();
			s.getTransaction().commit();
			return l.getIdLiquidacion();
		}
		catch (Exception ex){
			ex.printStackTrace();
			
		}
		return null;
	}
	
	public void grabarDetalleLiquidaciones(List<DetalleLiquidacion> detalleLiquidaciones){
		try{
			Session s = getSession();
			s.beginTransaction();
			for(DetalleLiquidacion detalleLiquidacion: detalleLiquidaciones) {
				s.merge(detalleLiquidacion);
			}
			s.flush();
			s.getTransaction().commit();
		}
		catch (Exception ex){
			ex.printStackTrace();
			
		}
	}
		
	public void modificarPeso (Peso p) {
		try{
		Session s = getSession();
		s.beginTransaction();
		s.update(p);
		s.flush();
		s.getTransaction().commit();
		}
		catch (Exception ex){
			ex.printStackTrace();
			
		}
	}
	
	public void modificarSubclase (SubClase sc)	{
		try{
		Session s = getSession();
		s.beginTransaction();
		s.update(sc);
		s.flush();
		s.getTransaction().commit();
		}
		catch (Exception ex){
			ex.printStackTrace();
			
		}
	}
	
	public void modificarProducto (Producto p) {
		try{
		Session s = getSession();
		s.beginTransaction();
		s.update(p);
		s.flush();
		s.getTransaction().commit();
		}
		catch (Exception ex){
			ex.printStackTrace();
			
		}
	}
		
	public void modificarEmpresaDeTransporte(EmpresaTransporte emp)	{
		try{
		Session s = getSession();
		s.beginTransaction();
		s.update(emp);
		s.flush();
		s.getTransaction().commit();
		}
		catch (Exception ex){
			ex.printStackTrace();
			
		}
	}
		
	public void modificarCodigoPostal (CodigoPostal cp) {
		try{
		Session s = getSession();
		s.beginTransaction();
		s.update(cp);
		s.flush();
		s.getTransaction().commit();
		}
		catch (Exception ex){
			ex.printStackTrace();
			
		}
	}
	
	public void modificarTarifa (Tarifa t) {
		try{
		Session s = getSession();
		s.beginTransaction();
		s.update(t);
		s.flush();
		s.getTransaction().commit();
		}
		catch (Exception ex){
			ex.printStackTrace();
			
		}
	}
	
	public void modificarLiquidacion (Liquidacion l) {
		try{
		Session s = getSession();
		s.beginTransaction();
		s.update(l);
		s.flush();
		s.getTransaction().commit();
		}
		catch (Exception ex){
			ex.printStackTrace();
			
		}
	}
	
	public void removerPeso(Peso p) {
		try{
			Session s = getSession();
			s.beginTransaction();
			s.delete(p);
			s.flush();
			s.getTransaction().commit();
		}
			catch (Exception ex){
				ex.printStackTrace();
			
		}
	}	
	
	public void removerSubClase(SubClase sc) {
		try{
			
		Session s = getSession();
		s.beginTransaction();
		s.delete(sc);
		s.flush();
		s.getTransaction().commit();
		}
		catch (Exception ex){
			ex.printStackTrace();
			
		}
	}
	
	public void removerProducto(Producto p) {
		try{
		Session s = getSession();
		s.beginTransaction();
		s.delete(p);
		s.flush();
		s.getTransaction().commit();
		}
		catch (Exception ex){
			ex.printStackTrace();
			
		}
	}
	
	public void removerEmpresaDeTransporte(EmpresaTransporte emp) {
		try{
			
		Session s = getSession();
		s.beginTransaction();
		s.delete(emp);
		s.flush();
		s.getTransaction().commit();
		}
		catch (Exception ex){
			ex.printStackTrace();
			
		}
		
	}
		
	public void removerCodigoPostal(CodigoPostal cp) {
		try{
		Session s = getSession();
		s.beginTransaction();
		s.delete(cp);
		s.flush();
		s.getTransaction().commit();
		}
		catch (Exception ex){
			ex.printStackTrace();
			
		}
	}
	
	public void removerTarifa(Tarifa t) {
		try{
		Session s = getSession();
		s.beginTransaction();
		s.delete(t);
		s.flush();
		s.getTransaction().commit();
		}
		catch (Exception ex){
			ex.printStackTrace();
			
		}
	}
	
	public HashSet<Peso> obtenerPesos() {
		try{		
			Session s = getSession();
			HashSet<Peso> pesos = new HashSet<Peso>();
			@SuppressWarnings("unchecked")
			Iterator<Peso> iter = s.createQuery("from Peso").list().iterator();
			while (iter.hasNext()) 
			{
				pesos.add(iter.next());
			}
			return pesos;			
		}
		catch (Exception ex){
			ex.printStackTrace();
			return null;
		}
	}
	
	public HashSet<SubClase> obtenerSubclases() {
		try{
			Session s = getSession();
			HashSet<SubClase> subClases = new HashSet<SubClase>();
			@SuppressWarnings("unchecked")
			Iterator<SubClase> iter = s.createQuery("from SubClase").list().iterator();
			while (iter.hasNext())
			{
				subClases.add(iter.next());
			}			
			return subClases;
		}
		catch (Exception ex){
			ex.printStackTrace();
			return null;
		}
	}
	
	public HashSet<Producto> obtenerProductos() {
		try{
			Session s = getSession();
			HashSet<Producto> productos = new HashSet<Producto>();
			@SuppressWarnings("unchecked")
			Iterator<Producto> iter = s.createQuery("from Producto").list().iterator();
			while (iter.hasNext())
			{
				productos.add(iter.next());
			}			
			return productos;			
		}
		catch (Exception ex){
			ex.printStackTrace();
			return null;
		}
	}
		
	@SuppressWarnings("unchecked")
	public HashSet<EmpresaTransporte> obtenerEmpresasDeTransportes() {
		try{
			Session s = getSession();
			HashSet<EmpresaTransporte> emp = new HashSet<EmpresaTransporte>();
			Iterator<EmpresaTransporte> iter =s.createQuery("from EmpresaTransporte").list().iterator();
			while (iter.hasNext())
			{
				emp.add(iter.next());
			}			
			return emp;
		}
		catch (Exception ex){
			ex.printStackTrace();
			return null;
		}
	}
	
	public HashSet<CodigoPostal> obtenerCodigosPostales() {
		try{
			Session s = getSession();
			HashSet<CodigoPostal> cp = new HashSet<CodigoPostal>();
			@SuppressWarnings("unchecked")
			Iterator<CodigoPostal> iter = s.createQuery("from CodigoPostal").list().iterator();
			while (iter.hasNext())
			{
				cp.add(iter.next());
			}			
			return cp;
		}
		catch (Exception ex){
			ex.printStackTrace();
			return null;
		}
	}
	
	public HashSet<Tarifa> obtenerTarifa() {
		try{
			Session s = getSession();
			HashSet<Tarifa> t = new HashSet<Tarifa>();
			@SuppressWarnings("unchecked")
			Iterator<Tarifa> iter = s.createQuery("from Tarifa").list().iterator();
			while (iter.hasNext())
			{
				t.add(iter.next());
			}
			return t;
		}
		catch (Exception ex){
			ex.printStackTrace();
			return null;
		}
	}
	
	public CodigoPostal obtenerCodigoPostal(String codigoPostal, Integer sector){
		try	{
			Session s = getSession();
			CodigoPostal cp = (CodigoPostal) s.createQuery("from CodigoPostal cp " +
					"where cp.idCodPostal.idCodigoPostal=:idCodPostal " +
					"and cp.idCodPostal.sector=:sector").setParameter("idCodPostal", codigoPostal)
					.setParameter("sector", sector).uniqueResult();			
			return cp;
		}
		catch ( Exception ex){
			
			ex.printStackTrace();
			return null;
		}
	}
	
	public Producto obtenerProducto(Integer nroProducto){
		try{
			Session s = getSession();
			Producto p = (Producto) s.createQuery("from Producto p " +
					"where p.idProducto=:idProducto").setParameter("idProducto", nroProducto)
					.uniqueResult();			
			return p;
		}
		catch (Exception ex){
			ex.printStackTrace();
			return null;
		}
	}
	
	public EmpresaTransporte obtenerEmpresaTransporteByCUIT(String cuit){
		try{
			Session s = getSession();
			EmpresaTransporte et = (EmpresaTransporte) s.createQuery("from EmpresaTransporte ep " +
					"where ep.cuit=:cuit").setParameter("cuit", cuit).uniqueResult();			
			return et;
		}
		catch (Exception ex){
			ex.printStackTrace();
			return null;
		}
	}
	
	public Tarifa obtenerTarifaByIdentificador(Integer idEmpresaTransporte, String codigoPostal, Integer sector){
		try{
			Session s = getSession();
			Tarifa t = (Tarifa) s.createQuery("from Tarifa t " +
					"where t.empresaTransporte.idEmpresaTransporte=:idEmpresaTransporte " +
					"and t.codigoPostal.idCodPostal.idCodigoPostal=:idCodPostal " +
					"and t.codigoPostal.idCodPostal.sector=:sector")
					.setParameter("idEmpresaTransporte", idEmpresaTransporte)
					.setParameter("idCodPostal", codigoPostal)
					.setParameter("sector", sector).uniqueResult();			
			return t;
		}
		catch (Exception ex){
			ex.printStackTrace();
			return null;
		}
	}
	
	public Liquidacion obtenerLiquidacion(Integer idLiquidacion){
		try{
			Session s = getSession();
			Liquidacion l = (Liquidacion) s.createQuery("from Liquidacion l " +
					"where l.idLiquidacion=:idLiquidacion").setParameter("idLiquidacion", idLiquidacion)
					.uniqueResult();			
			return l;
		}
		catch (Exception ex){
			ex.printStackTrace();
			return null;
		}
	}
	
	public HashSet<DetalleLiquidacion> obtenerDetallesLiquidacion(Integer idLiquidacion){
		try{
			Session s = getSession();
			HashSet<DetalleLiquidacion> detalles=new HashSet<DetalleLiquidacion>();
			@SuppressWarnings("unchecked")
			List<DetalleLiquidacion> detallesLiquidacion = s.createQuery("from DetalleLiquidacion dl " +
					"where dl.idLiquidacion=:idLiquidacion").setParameter("idLiquidacion", idLiquidacion)
					.list();
			for (DetalleLiquidacion detalle: detallesLiquidacion)
			{
				detalles.add(detalle);
			}
			return detalles;
		}
		catch (Exception ex){
			ex.printStackTrace();
			return null;
		}
	}
}
